<template>
  <div>
    <!-- 1.5完成加载更多的滚动条 van-list 需要包裹着列表内容 -->
    <!-- offset:设置滚动条与底部距离小于(50) offset时触发load事件 -->
    <!-- created和onLoad会一进入页面都会请求一次后台数据，这样会拿到2次第一页数据
         需要把onLoad的immediate-check关闭 -->
    <!-- List组件通过loading和finished两个变量控制加载状态，当组件滚动条到底部时，
         会触发load事件默认把loading设置成true，此时就可以发起异步操作并更新数据，
         数据更新完毕后，手动将loading设置成false否则无法下次请求数据，如果数据全部加载完毕，
         需要判断直接把finished设置成ture就可以显示finished-text -->
    <!-- 1.6实现下拉刷新 --需要包裹滚动条和频道列表 -->
    <!-- 刷新流程：页码回到第一页，现有数据数组清空，重新调用获取文章接口 -->
    <!-- 刷新要把旧数组清空, 时间回到系统时间, 重新发起一次请求, 第一页数据 -->
    <!-- 一定注意, 数据异步刷新完毕, 要关闭isLoading状态 -->
    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
      <van-list
        v-model="loading"
        :finished="finished"
        finished-text="没有更多了"
        :offset="50"
        :immediate-check="false"
        @load="onLoad"
      >
        <!-- 首页点击文章，跳转详情 -->
        <!-- 知识点：1.组件上通过@绑定的事件 会被认为是自定义事件(子传父)
                  所以这个的click也会被认为是自定义事件 但是子组件中还没有定义this.$emit
                  这样点击事件不会生效
                  2.自定义组件上绑定原生事件的解决方法
                  方法一：.native事件修饰符 是用来描述当前的click是一个原生点击事件
                  告诉vue和子传父的自定义事件无关就可以实现点击
                  方法二：在子组件的created钩子中定义一个子传父的自定义事件this.$emit名字也叫click
                  在父组件中就可以给子组件绑定名字叫click事件
                           -->
        <Articleitem
          v-for="item in articlesList"
          :key="item.art_id"
          :obj="item"
          @click.native="$router.push(`/articledetail?aid=${item.art_id}`)"
        ></Articleitem>
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
// 获取新闻列表的接口数据渲染组件--然后把对象传递给子组件(Articleitem)渲染内容
import { articlesListAPI } from '@/api'
import Articleitem from './ArticleItem.vue'
import { timeAgo } from '../../../utils/date'
export default {
  // 1.4数据是父组件传递过来的id主要是去请求不同频道接口的数据
  props: {
    cid: Number
  },
  components: {
    Articleitem
  },
  data () {
    return {
      articlesList: [],
      loading: false,
      finished: false,
      nextTime: null, // 声明一个变量为了接收前一页的时间戳
      refreshing: false
    }
  },
  created () {
    this.getArticleList()
  },
  methods: {
    // 1.6 封装一个函数--方便created()和onLoad()调用
    // getArticleList是后端接口需要两个参数一个是频道id一个是timestamp
    // 如果滑倒下一页需要传递之前的时间戳如果是刷新需要当前的时间戳
    // 分析如何拿到下一页数据, 发现接口文档有个timestamp, 说明下一页要用上一次请求成功的pre_timestamp的值
    async getArticleList () {
      const res = await articlesListAPI({
        channelId: this.cid,
        timestamp: this.nextTime
      })
      // 直接在后台得到的数据直接时间转换(得到时间戳转换成多 少之年前)
      res.data.data.results.forEach((item) => {
        item.pubdate = timeAgo(item.pubdate)
      })
      // this.articlesList = res.data.data.results
      // 如果请求数据为空了将finished改成ture直接结束
      if (res.data.data.results.length === 0) {
        this.finished = true
      } else {
        // 保存下一页数据的时间(做分页用)这样可以记录页面
        this.nextTime = res.data.data.pre_timestamp
        // 合并前面请求的数据和即将请求是数据合并
        this.articlesList = [...this.articlesList, ...res.data.data.results]
        this.loading = false // 底部触底加载更多
      }
    },
    // 底部加载
    onLoad () {
      // 有第一页数据以后，onLoad再发请求
      if (this.articlesList.length > 0) {
        this.getArticleList()
      }
    },
    // 下拉刷新
    onRefresh () {
      // 因为要重新获取最新的数据所以需要将nextTime设置成null
      this.nextTime = null
      // 因为刷新之后数据是全新 所以需要先将旧存储的数据清空
      this.articlesList = []
      // 调用接口 重新获取数据
      this.getArticleList()
      // 刷新中会把refreshing状态改成ture 刷新完毕, 要手动关闭isLoading状态
      // 为了下一次刷新做准备否则无法刷新
      this.refreshing = false
    }
  }
}
</script>

<style></style>
